/**
 * @Title: AuthFacade.java
 * @Package com.yly.module.sys.security.dynamic
 * @Description: TODO
 * @author zz
 * @date 2014-3-15 下午4:20:32
 * @version V1.0
 */
package com.yly.module.sys.security.dynamic;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.stereotype.Component;

import com.yly.module.sys.security.dynamic.auth.IAuthService;


/**
 * @ClassName: AuthFacade
 * @Description: TODO
 * @author zz
 * @date 2014-3-15 下午4:20:32
 */
@Component
public class AuthFacade {

	protected static Log log = LogFactory.getLog(AuthFacade.class);
	
	private static final String CRLF = "\r\n";

	private static final String LAST_AUTH_STR = "/**=authc";
	
	@Resource
	private List<IAuthService> authList = new ArrayList<IAuthService>();

	@Resource
	private ShiroFilterFactoryBean shiroFilterFactoryBean;

	/**
	 * 重新构建权限过滤器 一般在修改了用户角色、用户等信息时，需要再次调用该方法
	 */
	public synchronized void reCreateFilterChains() {

		AbstractShiroFilter shiroFilter = null;
		try {
			shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean
					.getObject();
		} catch (Exception e) {
			log.error("getShiroFilter from shiroFilterFactoryBean error!", e);
			throw new RuntimeException(
					"get ShiroFilter from shiroFilterFactoryBean error!");
		}

		PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter
				.getFilterChainResolver();
		DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver
				.getFilterChainManager();

		// 清空老的权限控制
		manager.getFilterChains().clear();

		shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
		shiroFilterFactoryBean
				.setFilterChainDefinitions(loadFilterChainDefinitions());
		// 重新构建生成
		Map<String, String> chains = shiroFilterFactoryBean
				.getFilterChainDefinitionMap();
		for (Map.Entry<String, String> entry : chains.entrySet()) {
			String url = entry.getKey();
			String chainDefinition = entry.getValue().trim().replace(" ", "");
			manager.createChain(url, chainDefinition);
		}
	}
	
	private String loadFilterChainDefinitions(){
		StringBuilder definitions = new StringBuilder("");
		for(IAuthService as : authList){
			definitions.append(as.loadFilterChainDefinitions()).append(CRLF);
		}
		definitions.append(LAST_AUTH_STR).append(CRLF);
		return definitions.toString();
	}

	public List<IAuthService> getAuthList() {
		return authList;
	}

	public void setAuthList(List<IAuthService> authList) {
		this.authList = authList;
	}

	public ShiroFilterFactoryBean getShiroFilterFactoryBean() {
		return shiroFilterFactoryBean;
	}

	public void setShiroFilterFactoryBean(
			ShiroFilterFactoryBean shiroFilterFactoryBean) {
		this.shiroFilterFactoryBean = shiroFilterFactoryBean;
	}

	
	
}
